﻿#region The MIT License
// The MIT License
// 
// Copyright (c) 2009 octalforty studios
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#endregion
using System.Linq;

using NUnit.Framework;

using octalforty.Chinchillin.Console.Compiler;
using octalforty.Chinchillin.Console.Compiler.SemanticModel;

using Rhino.Mocks;

namespace octalforty.Chinchillin.Tests.Core.Compiler
{
    [TestFixture()]
    public class CdmCompilerTestFixture
    {
        [Test()]
        public void Compile()
        {
            var mocks = new MockRepository();
            var placeholderResolver = mocks.StrictMock<IPlaceholderResolver>();

            using(mocks.Record())
            {
                Expect.Call(placeholderResolver.ResolvePlaceholder("backupLocation")).Return(@"d:/backups/").Repeat.Any();
                Expect.Call(placeholderResolver.ResolvePlaceholder("backupDate")).Return(@"20100217").Repeat.Any();
                Expect.Call(placeholderResolver.ResolvePlaceholder("server-name")).Return(@"192.168.0.98").Repeat.Any();
            } // using

            mocks.ReplayAll();

            DeploymentManifest deploymentManifest = null;

            try
            {
                var compiler = new CdmCompiler(placeholderResolver);
                deploymentManifest = compiler.Compile(@"deployment-manifest version => ""1.0""
    def server name => web, address => ""$(server-name)"", login => administrator, password => password
    def server name => db, address => ""192.168.0.99""

    def task name => ""backup-web""
        exec fs:backup-directory directory-location => ""web://c:/inetpub/wwwroot/waffle.com/"", backup-location => ""web://$(backupLocation)""

       rollback
           exec fs:delete-directory location => ""web://$(backupLocation)""
       end
    end
            
    def task name => ""backup-db""
        exec db:backup-database database => ""db://sqlserver2008/sqlexpress/waffle"", backup-resource => ""db://d:/backups/waffle/waffle_$(backupDate).bak""
    end
        
    def task name => ""deploy-waffle.com"", depends-on => [""backup-web"", ""backup-db""]
        exec web:stop-web-application web-application => ""web://iis7/waffle.com"", app-offline-resource => ""local:///./resources/app_offline.htm""
        
        exec scm:stop-service service => ""web://scheduler""
        exec fs:sync-directory source-location => ""local://./published/waffle.com/"", target-location => ""web://c:/inetpub/wwwroot""/*, ignore => [""app_offline.htm""]*/
        
        exec db:upgrade-database database => ""db://sqlserver2008/sqlexpress/waffle"", migration-resource => ""local:///./db/waffle.mdl""
        
        exec scm:start-service service => ""web://scheduler""
        exec web:start-web-application web-application => ""web://iis7/waffle.com""
    end
end");
            } // try
            catch(CdmCompilationException e)
            {
                Assert.Fail(e.ToString());
            } // catch

            Assert.AreEqual(2, deploymentManifest.Servers.Count);

            Assert.AreEqual("web", deploymentManifest.Servers[0].Name);
            Assert.AreEqual("192.168.0.98", deploymentManifest.Servers[0].Address);
            Assert.AreEqual("administrator", deploymentManifest.Servers[0].Credentials.UserName);
            Assert.AreEqual("password", deploymentManifest.Servers[0].Credentials.Password);

            Assert.AreEqual("db", deploymentManifest.Servers[1].Name);
            Assert.AreEqual("192.168.0.99", deploymentManifest.Servers[1].Address);
            Assert.IsEmpty(deploymentManifest.Servers[1].Credentials.UserName);
            Assert.IsEmpty(deploymentManifest.Servers[1].Credentials.Password);

            Assert.AreEqual(3, deploymentManifest.Tasks.Count);

            Assert.AreEqual("backup-web", deploymentManifest.Tasks[0].Name);
            Assert.AreEqual(1, deploymentManifest.Tasks[0].Commit.Count);
            Assert.AreEqual(1, deploymentManifest.Tasks[0].Rollback.Count);

            Assert.AreEqual("web://d:/backups/", deploymentManifest.Tasks[0].Commit[0].Properties["backup-location"]);
            Assert.AreEqual("web://d:/backups/", deploymentManifest.Tasks[0].Rollback[0].Properties["location"]);

            Assert.AreEqual("backup-db", deploymentManifest.Tasks[1].Name);
            Assert.AreEqual(1, deploymentManifest.Tasks[1].Commit.Count);

            Assert.AreEqual("db://d:/backups/waffle/waffle_20100217.bak", deploymentManifest.Tasks[1].Commit[0].Properties["backup-resource"]);

            Assert.AreEqual("deploy-waffle.com", deploymentManifest.Tasks[2].Name);
            Assert.AreEqual(new [] { "backup-web", "backup-db" }, deploymentManifest.Tasks[2].DependsOn.ToArray());
            Assert.AreEqual(6, deploymentManifest.Tasks[2].Commit.Count);
            
        }
    }
}
